{"componentChunkName":"component---src-templates-blog-post-js","path":"/Easy-Dark-Mode-Switch-with-React-and-localStorage/","result":{"data":{"site":{"siteMetadata":{"title":"Aleks Popovic - personal website and blog"}},"markdownRemark":{"id":"0cebb04e-a49a-5da2-8cb9-ad9126eda043","excerpt":"Having a dark mode on your website or application has become very popular. Many big websites and applications are coming up with their own version of it and if…","html":"<p>Having a dark mode on your website or application has become very popular. Many big websites and applications are coming up with their own version of it and if you want to make one for your own react app you can easily do so with very little JavaScript code and a bit of custom CSS.</p>\n<p>I am going to show you how you can make a simple, yet versatile React component which you can use to change your website’s mode from light to dark. If you want you can later expand it to handle multiple application skins or themes.</p>\n<p>If you prefer a video version you can watch me create this Dark Mode component on Youtube:</p>\n<div class=\"gatsby-resp-iframe-wrapper\" style=\"padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; margin-bottom: 1.0725rem\" > <iframe src=\"https://www.youtube.com/embed/IiUg-2dAd4A\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen style=\" position: absolute; top: 0; left: 0; width: 100%; height: 100%; \"></iframe> </div>\n<p>I started a new create-react-app project and I’ve modified it a bit by adding some HTML to the App component. There is a simple nav bar, some text paragraphs and an image div that we will use to show how to switch image backgrounds between different page modes.</p>\n<p>I also created a new component in the components folder and named it DarkMode.js. We will also add a CSS file for styling it which we will call DarkMode.css. We can import both of them in the App component right away.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">\"react\"</span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">import</span> <span class=\"token string\">\"./styles/App.css\"</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token keyword\">import</span> DarkMode <span class=\"token keyword\">from</span> <span class=\"token string\">\"./components/DarkMode\"</span></span>\n<span class=\"token keyword\">function</span> <span class=\"token function\">App</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">className</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>App<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span>\n<span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>nav</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>a</span> <span class=\"token attr-name\">href</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>/<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Home</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>a</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>a</span> <span class=\"token attr-name\">href</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>/<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Projects</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>a</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>a</span> <span class=\"token attr-name\">href</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>/<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">About</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>a</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>a</span> <span class=\"token attr-name\">href</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>/<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Contact</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>a</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">DarkMode</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>nav</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">Hello World</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>h1</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span> <span class=\"token attr-name\">id</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>image<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eget</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        scelerisque neque, quis scelerisque erat. Quisque venenatis molestie</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        sapien, dapibus viverra nulla hendrerit eget. Pellentesque egestas</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        ultrices accumsan. Ut ac magna vel ex maximus ultricies. Nulla facilisi.</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        Suspendisse gravida sem eu odio mattis ullamcorper. Curabitur feugiat</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        ipsum vel vulputate ultricies.</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        Praesent pulvinar faucibus risus in iaculis. Sed erat felis, pretium sit</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        amet ultricies non, porta et lacus. Curabitur a urna mi. Sed eleifend</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        sed erat eget viverra. Quisque sit amet purus viverra massa posuere</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        congue. Suspendisse efficitur venenatis enim, id hendrerit enim ultrices</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">        sed. Nam sed dapibus nisi.</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>p</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\"></span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token plain-text\">    </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span></span>  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> App</code></pre></div>\n<p>We will start building out the component by making it a constant with no inputs and export it as a default. Its basic functionality is going to be returning a button element which we will use to change the mode or theme. Lets import the CSS file right away and we will change its contents later.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">\"react\"</span>\n<span class=\"token keyword\">import</span> <span class=\"token string\">\"../styles/DarkMode.css\"</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">DarkMode</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> DarkMode</code></pre></div>\n<p>For everything to work we need to set up a few properties.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">\"react\"</span>\n<span class=\"token keyword\">import</span> <span class=\"token string\">\"../styles/DarkMode.css\"</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">DarkMode</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">let</span> clickedClass <span class=\"token operator\">=</span> <span class=\"token string\">\"clicked\"</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> body <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span>body</span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> lightTheme <span class=\"token operator\">=</span> <span class=\"token string\">\"light\"</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> darkTheme <span class=\"token operator\">=</span> <span class=\"token string\">\"dark\"</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">let</span> theme</span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> DarkMode</code></pre></div>\n<p>The body is the document’s body element. We need a reference to it so we can apply different styling to it once we click the dark mode button. Light theme and dark theme are going to be the class names that we will apply to the body. Theme is a local property which we will use to handle the currently selected theme or mode.</p>\n<p>The clicked class is going to be applied to the button when we click on it. This way we will signal the change of its state. Since we are mentioning state you may be wondering if we will use react’s state to set up our logic and the answer is no, we will not. We could, but it’s a really simple use case that doesn’t require it. What we will do is use the local storage, which is browser’s internal memory space designed just for stuff like this. It has a limited memory capacity and it’s not considered secure, but it’s perfect for a situation like this where you just need to keep track of a single property value. Local storage is also very handy because its values persist when you switch the page or close the browser altogether, so you can set the values and not worry about them getting deleted or expiring.</p>\n<p>In terms of JavaScript - the local storage is an object which is a part of the window object, so we can access it directly and try to find an item that’s stored inside. For this we use the getItem function and pass in the property we are looking for.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">\"react\"</span>\n<span class=\"token keyword\">import</span> <span class=\"token string\">\"../styles/DarkMode.css\"</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">DarkMode</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> clickedClass <span class=\"token operator\">=</span> <span class=\"token string\">\"clicked\"</span>\n  <span class=\"token keyword\">const</span> body <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span>body\n  <span class=\"token keyword\">const</span> lightTheme <span class=\"token operator\">=</span> <span class=\"token string\">\"light\"</span>\n  <span class=\"token keyword\">const</span> darkTheme <span class=\"token operator\">=</span> <span class=\"token string\">\"dark\"</span>\n  <span class=\"token keyword\">let</span> theme\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>localStorage<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    theme <span class=\"token operator\">=</span> localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">getItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"theme\"</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\"></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>theme <span class=\"token operator\">===</span> lightTheme <span class=\"token operator\">||</span> theme <span class=\"token operator\">===</span> darkTheme<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    body<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>theme<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    body<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>lightTheme<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> DarkMode</code></pre></div>\n<p>In this case we will be expecting to find one of the two values - light or dark, because these are the values we will be setting in the local storage. If we find such value we will add that CSS class to the document body. If not we will default to not using the dark mode by setting the light class. Of course, if you want dark mode to be the default value you can do that too.</p>\n<p>To make our button do something on click we need to set up an on click event for it which we’ll call the switchTheme function. We will also add an id to it so we can style it more easily later, and we will add the clicked class to it if the dark mode is on.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"language-jsx\"><code class=\"language-jsx\"><span class=\"token keyword\">import</span> React <span class=\"token keyword\">from</span> <span class=\"token string\">\"react\"</span>\n<span class=\"token keyword\">import</span> <span class=\"token string\">\"../styles/DarkMode.css\"</span>\n\n<span class=\"token keyword\">const</span> <span class=\"token function-variable function\">DarkMode</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> clickedClass <span class=\"token operator\">=</span> <span class=\"token string\">\"clicked\"</span>\n  <span class=\"token keyword\">const</span> body <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span>body\n  <span class=\"token keyword\">const</span> lightTheme <span class=\"token operator\">=</span> <span class=\"token string\">\"light\"</span>\n  <span class=\"token keyword\">const</span> darkTheme <span class=\"token operator\">=</span> <span class=\"token string\">\"dark\"</span>\n  <span class=\"token keyword\">let</span> theme\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>localStorage<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    theme <span class=\"token operator\">=</span> localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">getItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"theme\"</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>theme <span class=\"token operator\">===</span> lightTheme <span class=\"token operator\">||</span> theme <span class=\"token operator\">===</span> darkTheme<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    body<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>theme<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    body<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>lightTheme<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">const</span> <span class=\"token function-variable function\">switchTheme</span> <span class=\"token operator\">=</span> <span class=\"token parameter\">e</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>theme <span class=\"token operator\">===</span> darkTheme<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      body<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">replace</span><span class=\"token punctuation\">(</span>darkTheme<span class=\"token punctuation\">,</span> lightTheme<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">remove</span><span class=\"token punctuation\">(</span>clickedClass<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"theme\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"light\"</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      theme <span class=\"token operator\">=</span> lightTheme</span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">      body<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">replace</span><span class=\"token punctuation\">(</span>lightTheme<span class=\"token punctuation\">,</span> darkTheme<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>classList<span class=\"token punctuation\">.</span><span class=\"token function\">add</span><span class=\"token punctuation\">(</span>clickedClass<span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      localStorage<span class=\"token punctuation\">.</span><span class=\"token function\">setItem</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"theme\"</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"dark\"</span><span class=\"token punctuation\">)</span></span><span class=\"gatsby-highlight-code-line\">      theme <span class=\"token operator\">=</span> darkTheme</span><span class=\"gatsby-highlight-code-line\">    <span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span></span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n    <span class=\"token operator\">&lt;</span>button\n<span class=\"gatsby-highlight-code-line\">      className<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span>theme <span class=\"token operator\">===</span> <span class=\"token string\">\"dark\"</span> <span class=\"token operator\">?</span> clickedClass <span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\">      id<span class=\"token operator\">=</span><span class=\"token string\">\"darkMode\"</span></span><span class=\"gatsby-highlight-code-line\">      onClick<span class=\"token operator\">=</span><span class=\"token punctuation\">{</span><span class=\"token parameter\">e</span> <span class=\"token operator\">=></span> <span class=\"token function\">switchTheme</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span>    <span class=\"token operator\">></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> DarkMode</code></pre></div>\n<p>The switch theme function is going to check which theme is currently active and do a couple of different things depending on that. If the dark mode is currently on it will replace the dark theme body class with the light one. It will remove the clicked class from the dark mode button and set the local storage theme property to light. Finally, we will set the theme property to light theme, since dark mode will no longer be active.</p>\n<p>In case the dark mode was already off we will want to turn it on. To do that we will do almost the same thing as before. We replace the light theme body class with the dark one, mark the button as clicked, set the local storage property to dark and finally set the theme to dark.</p>\n<p>With this, our component is finished and we can import it inside of the App component. Now we need to set up its CSS.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">#darkMode</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">background</span><span class=\"token punctuation\">:</span> transparent <span class=\"token url\"><span class=\"token function\">url</span><span class=\"token punctuation\">(</span>\"../moon.png\"<span class=\"token punctuation\">)</span></span> no-repeat center<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-size</span><span class=\"token punctuation\">:</span> 30px 30px<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">width</span><span class=\"token punctuation\">:</span> 45px<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">height</span><span class=\"token punctuation\">:</span> 45px<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">filter</span><span class=\"token punctuation\">:</span> <span class=\"token function\">grayscale</span><span class=\"token punctuation\">(</span>100%<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">border</span><span class=\"token punctuation\">:</span> none<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">border-radius</span><span class=\"token punctuation\">:</span> 50%<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">transition</span><span class=\"token punctuation\">:</span> background-color 0.3s ease-in-out<span class=\"token punctuation\">,</span> filter 0.3s ease-in-out<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token selector\">#darkMode:hover,\n#darkMode:focus</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">filter</span><span class=\"token punctuation\">:</span> none<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-color</span><span class=\"token punctuation\">:</span> black<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">cursor</span><span class=\"token punctuation\">:</span> pointer<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token selector\">#darkMode.clicked</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">filter</span><span class=\"token punctuation\">:</span> none <span class=\"token important\">!important</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-color</span><span class=\"token punctuation\">:</span> black<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Our button has the dark mode Id so that’s what we will use to style it. For the background image I am using a <a href=\"https://www.flaticon.com/free-icon/moon_768442\">moon icon that I found on flaticon.com</a>. I am setting its dimensions and borders so it’s shaped like a circle and I’m adding it a grayscale filter so it looks grayed-out when in default non-clicked state.</p>\n<p>For hover and focus states we are going to remove the filter and set the background to black, so the icon looks like a yellow moon and stars with a night sky background. We will do the same for the clicked button class.</p>\n<p>Our components CSS is now set up and we need to take care of the two body classes, one for dark mode and one for light mode. To change between two different looks we will use CSS variables. You can declare them anywhere you want if the body element has access to them. As as start we will add two color variables in the root selector.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">:root</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">--blue</span><span class=\"token punctuation\">:</span> <span class=\"token function\">rgb</span><span class=\"token punctuation\">(</span>26<span class=\"token punctuation\">,</span> 57<span class=\"token punctuation\">,</span> 87<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--white</span><span class=\"token punctuation\">:</span> <span class=\"token function\">rgb</span><span class=\"token punctuation\">(</span>236<span class=\"token punctuation\">,</span> 236<span class=\"token punctuation\">,</span> 236<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>To simplify the example I will use the white color for background and the blue color for text in light mode and we will switch between them when we turn on the dark mode. To do so we will add more CSS variables inside of the light class selector, which will use the variables from the root. We will also modify the font weight when switching themes, as well as the background image below the hello world heading. This is not something I recommend doing, especially for the background image, but it is an option if you want to play around with it.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">body.light</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">--background-color</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--white<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--text-color</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--blue<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--font-weight</span><span class=\"token punctuation\">:</span> 400<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--image</span><span class=\"token punctuation\">:</span> <span class=\"token url\"><span class=\"token function\">url</span><span class=\"token punctuation\">(</span>\"../day.jpg\"<span class=\"token punctuation\">)</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>For the dark mode class we will do something similar. We will switch the colors for background and text, give the font a bit more weight and we’ll use a different night time image.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">body.dark</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">--background-color</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--blue<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--text-color</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--white<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--font-weight</span><span class=\"token punctuation\">:</span> 500<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">--image</span><span class=\"token punctuation\">:</span> <span class=\"token url\"><span class=\"token function\">url</span><span class=\"token punctuation\">(</span>\"../night.jpg\"<span class=\"token punctuation\">)</span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Now that we have dark and light mode classes set up we need to make the body selector use them, which is easy enough. Just set your properties to use the correct CSS variables. We can also set our background and color transition so the mode switch isn’t so sudden.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">body</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">background</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--background-color<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--text-color<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">font-weight</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--font-weight<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token property\">transition</span><span class=\"token punctuation\">:</span> background 0.3s ease-in-out<span class=\"token punctuation\">,</span> color 0.6s ease-in-out<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Of course, we also need to set up the image container to use the image variable.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">#image</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">width</span><span class=\"token punctuation\">:</span> 100%<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">height</span><span class=\"token punctuation\">:</span> 300px<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-attachment</span><span class=\"token punctuation\">:</span> fixed<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-position</span><span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-repeat</span><span class=\"token punctuation\">:</span> no-repeat<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-size</span><span class=\"token punctuation\">:</span> cover<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">transition</span><span class=\"token punctuation\">:</span> background-image 0.7s ease-in-out<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background-image</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--image<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>If we want to take this a bit further, we can also set up the nav bar to change the background and text color in different modes.</p>\n<div class=\"gatsby-highlight\" data-language=\"css\"><pre class=\"language-css\"><code class=\"language-css\"><span class=\"token selector\">nav</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">padding</span><span class=\"token punctuation\">:</span> 1rem 25%<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">margin</span><span class=\"token punctuation\">:</span> 0 auto<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">display</span><span class=\"token punctuation\">:</span> flex<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">justify-content</span><span class=\"token punctuation\">:</span> space-evenly<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">align-items</span><span class=\"token punctuation\">:</span> center<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">background</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--text-color<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token selector\">nav a</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">text-decoration</span><span class=\"token punctuation\">:</span> none<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">text-transform</span><span class=\"token punctuation\">:</span> uppercase<span class=\"token punctuation\">;</span>\n  <span class=\"token property\">color</span><span class=\"token punctuation\">:</span> <span class=\"token function\">var</span><span class=\"token punctuation\">(</span>--background-color<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>If you followed through everything you should now have your own functioning customizable dark mode switch built in React. If you want to take a closer look at the project code you can grab the source files on <a href=\"https://github.com/alekspopovic/DarkMode\">GitHub</a> along with all of the images I used for it.</p>\n<hr>\n<div class=\"sectionHighlight\">If you have any questions or comments you can reach out to me on <a href=\"https://twitter.com/alekswritescode\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter</a> and <a href=\"https://www.instagram.com/aleks.popovic/\" target=\"_blank\" rel=\"noopener noreferrer\">Instagram</a>, where I also post interesting code tidbits and designs.\n<p>I also have a <a href=\"https://www.youtube.com/AleksPopovic\" target=\"_blank\" rel=\"noopener noreferrer\">YouTube channel</a> where I regularly upload React and web dev tutorials, so if that’s your cup of tea feel free to support me by subscribing.</div></p>","frontmatter":{"title":"Easy Dark Mode Switch with React and localStorage","series":null,"seriesLink":null,"date":"September 12, 2020","description":"Having a dark mode on your website or application has become very popular. Many big websites and applications are coming up with their own version of it and if you want to make one for your own React app you can easily do so with very little JavaScript code and a bit of custom CSS. ","tags":["web","react"],"featuredImage":{"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACOElEQVQozy3Q20+SARzGcf6MDpum8b4vumVbJ0xJE21qpqV4gNpCFGUKCuIJQxQUms5Dp6WZZRZMw5IVtaKc1YWtg6sLr2y5ddG6aG2tLrv69r7UxXP7+f2eRyWU+hBrxxEbZ5C6ltD4nyL5E0g9MSRvHLFhBnWOE3VeJ2JBL6n7jOwQCkg7YEXQdaDObZfjRMhpRzjchkoTSKA5v4oUXEEafILYHyfTc48MVwSxPYxgmUIyhNDUjpGqd2OrqWIx5MJsamDXITvif0id7UCQo9J4Yqg7ltFafZyoLeN4VTGVZ6vRm8zU1egw1BVisBjJNE2w55iDoK2B9chVpoNB1NpWBK1dhuxJTK18KMkfpDfOkd90DqPNRGNPExWuTsqd3Vi6LJht1VTWN7GzaJDskk5udzi473Ey6fGxPatZRv+BCqbUVkmuBbnaAkenVsmfiFM09Rz9ZDwZXWABqTxAirzdwdNjGJ2XsFYYsGZrGfeF5IPX5H3b2C1XT9ZWQMEwingqxBHvLDrvLfL98+QNzFEwNE/WmRDpeg/1zousvHpNZDFGt91NwN7Mxsd3/Pj9i3A0QZoCKlsmwUIPQkk/QrFXTj9ixRDiyWGkmhHSzNMUtlxhY2mWTy+WSUQjPLwTZmvtEV8/POPzxlu+b76n2DRMyv4WxFwFLB1AKPMjmi4gWqYRW+eR3FEyemOk9D3GHZxh6+5lNh/c4ProCI6WPt4s3eTbyyg/1+P8+bKG2zfLtr3NSDonfwESF2PaMFiJFwAAAABJRU5ErkJggg==","aspectRatio":2.6666666666666665,"src":"/static/c84963620317fe9242f44fecd322767a/0e6e2/darkNew.png","srcSet":"/static/c84963620317fe9242f44fecd322767a/b460a/darkNew.png 480w,\n/static/c84963620317fe9242f44fecd322767a/6e898/darkNew.png 960w,\n/static/c84963620317fe9242f44fecd322767a/0e6e2/darkNew.png 1920w","srcWebp":"/static/c84963620317fe9242f44fecd322767a/30cf3/darkNew.webp","srcSetWebp":"/static/c84963620317fe9242f44fecd322767a/35871/darkNew.webp 480w,\n/static/c84963620317fe9242f44fecd322767a/fcc10/darkNew.webp 960w,\n/static/c84963620317fe9242f44fecd322767a/30cf3/darkNew.webp 1920w","sizes":"(max-width: 1920px) 100vw, 1920px"}}}}}},"pageContext":{"slug":"/Easy-Dark-Mode-Switch-with-React-and-localStorage/","previous":{"excerpt":"Having different page files for different languages makes all of the page translations pretty contained and easy for access if something…","fields":{"slug":"/Translating-React-components/"},"frontmatter":{"date":"August 16, 2020","title":"Translating React components","series":"How to Build a Multilingual Website with Gatsby and React","description":"Having different page files for different languages makes all of the page translations pretty contained and easy for access if something needs to be changed or added later on. Separating page components is good because of searching algorithms and SEO. There is also no code duplication, since page components are mostly plain text or markdown. Non-page components are a bit different.","tags":["web","react","multilingual"],"featuredImage":{"id":"a3034fe9-222e-533f-93ea-8fe775679692","publicURL":"/static/23e2c2b486f8733000f90e001c759f59/translating.png","relativeDirectory":"Translating-React-components","relativePath":"Translating-React-components/translating.png"}}},"next":{"excerpt":"A couple of days ago I noticed something interesting in the Netflix mobile app. It has a Coming Soon page which shows movies and TV shows…","fields":{"slug":"/How-to-build-Netflix's-Coming-Soon-page-in-React/"},"frontmatter":{"date":"November 02, 2020","title":"How to build Netflix's Coming Soon page in React","series":null,"description":"A couple of days ago I noticed something interesting in the Netflix mobile app. It has a Coming Soon page which shows movies and TV shows that are soon coming to Netflix. It has a few interesting functionalities. It's loading data from somewhere and sorting it into cards. You can bookmark a movie to let Netflix know you want to be notified when it comes out. It has a cool, modern looking share menu for which you need to manage state.","tags":["web","react"],"featuredImage":{"id":"59c8483f-d2af-5184-adf0-53d144e51701","publicURL":"/static/7a22096a1108d65c7262e5302662aef1/netflix.png","relativeDirectory":"How-to-build-Netflix's-Coming-Soon-page-in-React","relativePath":"How-to-build-Netflix's-Coming-Soon-page-in-React/netflix.png"}}}}}}